package il.ac.tau.cvws.scrabblesidekick.server.engine.dictionary;

import il.ac.tau.cvws.scrabblesidekick.server.db.engine.DBInsertionHandler;
import il.ac.tau.cvws.scrabblesidekick.server.engine.dictionary.exception.DictionaryException;
import il.ac.tau.cvws.scrabblesidekick.server.util.exception.ExceptionConstant;
import il.ac.tau.cvws.scrabblesidekick.shared.constant.BoardConstants;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException;

/*
 * this class is used for parsing a dictionary file into the DB.
 * the parsing process is done by first insert the dictionary into the dictionaries table, then the letters and finally the words. 
 */
public class DictionaryFileParser 
{
	private DBInsertionHandler insertionHandler = new DBInsertionHandler();

	private int dictionaryId;
	private char[] charArr;
	private char[] valuesArr;

	public DictionaryFileParser(String dictionaryName, int leftRight, String dictionaryFilePath) throws DictionaryException
	{		
		FileInputStream fstream  = null;
		int count= 0;
		try 
		{
			dictionaryId = 1;//insertionHandler.insertDictionary(dictionaryName, leftRight);

			fstream = new FileInputStream(dictionaryFilePath);
			DataInputStream in = new DataInputStream(fstream);

			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;

			String charsLine  = br.readLine();
			String valuesLine = br.readLine();

			if (leftRight == 0)
			{
				StringBuffer reverseChars = new StringBuffer(charsLine);
				charsLine = reverseChars.reverse().toString();
			}
			
			charArr   = charsLine.toCharArray();
			valuesArr = valuesLine.toCharArray();

			//letterCharMap();

			while((strLine = br.readLine()) != null) 
			{
				if(strLine.length() == 0)
				{
					break;					
				}

				if(strLine.length() < 2 || strLine.length() >15)
				{
					continue;
				}

				int[] intWord = wordMap(strLine);

				insertionHandler.insertWordn(dictionaryId, intWord);
				count++;
			}

			in.close();
		}
		catch (Exception e)
		{
			System.out.println(count);
			throw new DictionaryException(ExceptionConstant.GENERAL_FAILURE, e);
		}
		finally
		{
			try
			{
				if (fstream != null)
				{
					fstream.close();
				}
			}
			catch (IOException e) {}
		}
	}
	
	/*
	 * LOGIC: The function map the letters of a word to their numerical index in alphbet
	 * INPUT: word- the word to translate,
	 * RETURN: a mapped array of the word to her indices.
	 * NOTE: the count of the alphaBet starts from 1
	 */
	private int[] wordMap(String word) 
	{
		char[] wordTemp = word.toCharArray();
		int[] intWord = new int[wordTemp.length];
		int j = 0;

		for(char c: wordTemp)
		{
			for(int i = 0; i < charArr.length; i++)
			{
				if(c == charArr[i])
				{
					intWord[j] = i + 1;

					j++;

					break;
				}
			}
		}

		return intWord;
	}
	
	/*
	 * LOGIC: The function inserts to DB the alphabet of the language. 
	 * NOTE: the first charcter is the empty tile in all language,the count of the alphaBet starts from 1
	 */
	@SuppressWarnings("unused")
	private void letterCharMap() throws DictionaryException
	{		
		try //Insert Joker
		{
			insertionHandler.insertLetter(dictionaryId, 0 , ' ', BoardConstants.EMPTY_TILE);
		} 
		catch (SQLException e) 
		{
			throw new DictionaryException(ExceptionConstant.GENERAL_FAILURE, e.getCause());
		}

		int     i = 0;
		int count = 1;

		for (char c : charArr)
		{
			try 
			{	
				int value = 0;
				
				if (i == valuesArr.length - 1)
				{
					value = Character.getNumericValue(valuesArr[i]);
					insertionHandler.insertLetter(dictionaryId, count, c, value);

					continue;
				}

				if ((valuesArr[i+1] >= '0') && (valuesArr[i+1] <= '9') && (valuesArr[i] == '1'))
				{
					value = 10 + Character.getNumericValue(valuesArr[i+1]);
					i += 3;
				}
				else
				{
					value = Character.getNumericValue(valuesArr[i]);
					i += 2;
				}
				
				insertionHandler.insertLetter(dictionaryId,count, c,value);
			} 
			catch (SQLException e) 
			{
				throw new DictionaryException(ExceptionConstant.GENERAL_FAILURE, e.getCause());
			}

			count++;
		}
	}
}

